{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "gpuClass": "standard"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2ag5-vOMfCxi"
      },
      "source": [
        "# Importing the required libraries"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "GOdD67p9eiEV"
      },
      "source": [
        "# Helper Libraries\n",
        "\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt\n",
        "import seaborn as sns"
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "OW6QtnCyfCKI",
        "outputId": "45edc646-9dbb-4835-c2f3-a828d90d5dd6"
      },
      "source": [
        "# TensorFlow and tf.keras\n",
        "\n",
        "import tensorflow as tf\n",
        "from tensorflow import keras\n",
        "\n",
        "print(tf.__version__)\n",
        "\n",
        "print(keras.__version__)"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "2.11.0\n",
            "2.11.0\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2AroiaEafP_Q"
      },
      "source": [
        "from keras.utils import np_utils\n",
        "from keras.models import Sequential \n",
        "from keras.layers import Dense, Dropout, BatchNormalization\n",
        "from keras.layers import Conv2D, MaxPooling2D, Flatten"
      ],
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gV3wX3msfSTM"
      },
      "source": [
        "from keras.datasets import mnist"
      ],
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O1bj_XFpfcm6"
      },
      "source": [
        "# Load the Data"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "LC9UkQXefUj4",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "b17f38d7-cd7a-45fd-ad62-099df7ab31bb"
      },
      "source": [
        "(X_train, y_train), (X_test, y_test) = mnist.load_data()"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n",
            "11490434/11490434 [==============================] - 0s 0us/step\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yylIphOCfhdt",
        "outputId": "501ce4be-e339-4000-b6aa-111cc7a1da24"
      },
      "source": [
        "X_train.shape"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(60000, 28, 28)"
            ]
          },
          "metadata": {},
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 716
        },
        "id": "2etQJqZDOMjt",
        "outputId": "d438dda0-8c8b-4cfb-ea28-b5e9fc0e7b45"
      },
      "source": [
        "plt.figure(figsize=(12, 12))\n",
        "np.random.seed(0)\n",
        "idx = np.random.randint(0, 60000, 9)\n",
        "\n",
        "for i in range(len(idx)):\n",
        "    plt.subplot(3, 3, i+1)\n",
        "    plt.title(y_train[idx[i]])\n",
        "    grid_data = np.reshape(X_train[idx[i]], (28,28))\n",
        "    plt.imshow(grid_data, cmap='gray')"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 864x864 with 9 Axes>"
            ],
            "image/png": "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0AUAAECU2F5sA1/84hfzbiF6++yzT94tANE6++yzg7V99923w+ebPXt2sPbOO+90+HxobJ06dQrWJkyYEKzttddeqfaxZs2aYG3vvfcO1oYMGRKsffWrXw3WDjrooGCtS5cuwVrIxRdfHKztuuuuwdqJJ54YrCU9JvWMO7oAAACIEoMuAAAAosSgCwAAgCgx6AIAACBKDLoAAACIEoMuAAAAosT2Yhv42te+lncLqMCcOXPybgGomS233DJY+/a3v53qte66665Uz4fGduCBBwZraW8hJknPPfdc2fVhw4YFj1m0aFGwNmPGjGCtubk5WOvWrVuwdt555wVr55xzTtn1TTbZJHjMN77xjWBto43C9zePO+64YM3dg7Wi444uAAAAosSgCwAAgCgx6AIAACBKDLoAAACIEoMuAAAAosSgCwAAgCi1ub2Ymd0o6XBJS9x9UGmtl6Q7JPWXNE/SMe6+LLs209W9e/dg7ROf+ETq11u1alVFtXrWt2/fYO2rX/1q6tf7xS9+kfo561WMmcX6rrrqqmBt6623DtZCWwT993//d/CY+++/v/2NocMaLa8vvfRS6ue89dZbg7Vzzz237HrSFmJZePfdd4O1cePGBWu/+93vyq5PmTIleMzGG28crB199NHB2gknnBCsffDBB8Fa0bXnju5ESYdusHa+pEfcfQdJj5Q+BlAME0VmgXoxUeQVyEybg667T5H01gbLwyVNKr0/SdKIdNsCUCkyC9QP8gpkq9JXRmty94Wl9xdJagp9opmNkjSqwusASEe7MktegULgeyyQkqpfAtjd3cyCrw3n7s2SmiUp6fMA1EZSZskrUCx8jwWqU+muC4vNrI8klf5ckl5LADJAZoH6QV6BlFR6R/c+SSMlXVb6897UOqqB/fbbL1jbd999U79e0m9HPvHEE6lfrwi6desWrPXr16+GnaCkrjPbiHbeeedgba+99qronG+++WbZ9TPOOKOi8yEz0ea1V69ewdpPfvKTYO3VV18N1u68885gbfny5e1rrKDeeeedsuvPPPNM8Jikrw+zZs0K1nbfffdgberUqcFa0bV5R9fMbpP0F0k7mdnrZnaKWsJ3kJm9IunA0scACoDMAvWDvALZavOOrrsfFygdkHIvAFJAZoH6QV6BbPHKaAAAAIgSgy4AAACixKALAACAKDHoAgAAIEpVv2BE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\n"
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "X_train.shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "5-o3beDsuNMP",
        "outputId": "3f5d92eb-52f9-4996-bffd-f79c03e59606"
      },
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(60000, 28, 28)"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eMJs7-s2fr8H"
      },
      "source": [
        "# Data Preprocessing"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WEUwHOLRfkgM"
      },
      "source": [
        "# Type Conversion of Columns\n",
        "X_train = X_train.astype('float32')\n",
        "X_test = X_test.astype('float32')\n",
        "\n",
        "# Normalization\n",
        "X_train = X_train/255\n",
        "X_test = X_test/255\n",
        "\n",
        "# Adding the channel\n",
        "X_train = X_train.reshape(60000, 28, 28, 1)\n",
        "X_test = X_test.reshape(10000, 28, 28, 1)"
      ],
      "execution_count": 9,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "v6C2JJCMfo_H",
        "outputId": "f8e81505-5db3-4376-8917-268e5f8ee728"
      },
      "source": [
        "# here we are having a class number for each image\n",
        "print(\"Class label of first image :\", y_train[0])\n",
        "\n",
        "# lets convert this into a 10 dimensional vector\n",
        "# ex: consider an image is 5 convert it into 5 => [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]\n",
        "# this conversion needed for MLPs \n",
        "\n",
        "Y_train = np_utils.to_categorical(y_train, 10) \n",
        "Y_test = np_utils.to_categorical(y_test, 10)\n",
        "\n",
        "print(\"After converting the output into a vector : \",Y_train[0])"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Class label of first image : 5\n",
            "After converting the output into a vector :  [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2BKs_8lFf1-5"
      },
      "source": [
        "# Building the Model"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "nz8JFHkvf1aP",
        "outputId": "5bc5ef22-a8a2-4d2b-f578-b3686c742325"
      },
      "source": [
        "# STEP-1 Define the Model\n",
        "\n",
        "model = None\n",
        "model = Sequential()\n",
        "\n",
        "# conv3-32\n",
        "model.add(Conv2D(32, kernel_size=(3, 3), padding='same', input_shape=(28, 28, 1), activation='relu', kernel_initializer='he_normal'))\n",
        "\n",
        "# conv3-64\n",
        "model.add(Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_normal'))\n",
        "\n",
        "# Maxpooling\n",
        "model.add(MaxPooling2D(pool_size=(2, 2)))\n",
        "model.add(Dropout(0.25))\n",
        "\n",
        "# Flatten\n",
        "model.add(Flatten())\n",
        "\n",
        "# FC-128\n",
        "model.add(Dense(128, activation='relu', kernel_initializer='he_normal'))\n",
        "model.add(Dropout(0.5))\n",
        "\n",
        "# FC-10\n",
        "model.add(Dense(10, activation='softmax'))\n",
        "\n",
        "\n",
        "# STEP-2 Compile the Model\n",
        "model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n",
        "\n",
        "\n",
        "# STEP-3 Fit the Model\n",
        "model.fit(X_train, Y_train, batch_size=128, epochs=10)\n"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/10\n",
            "469/469 [==============================] - 16s 10ms/step - loss: 0.2340 - accuracy: 0.9290\n",
            "Epoch 2/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0841 - accuracy: 0.9756\n",
            "Epoch 3/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0623 - accuracy: 0.9807\n",
            "Epoch 4/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0528 - accuracy: 0.9837\n",
            "Epoch 5/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0426 - accuracy: 0.9871\n",
            "Epoch 6/10\n",
            "469/469 [==============================] - 4s 10ms/step - loss: 0.0386 - accuracy: 0.9879\n",
            "Epoch 7/10\n",
            "469/469 [==============================] - 6s 12ms/step - loss: 0.0340 - accuracy: 0.9891\n",
            "Epoch 8/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0280 - accuracy: 0.9911\n",
            "Epoch 9/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0286 - accuracy: 0.9903\n",
            "Epoch 10/10\n",
            "469/469 [==============================] - 5s 10ms/step - loss: 0.0232 - accuracy: 0.9920\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f13b7a9dac0>"
            ]
          },
          "metadata": {},
          "execution_count": 11
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4G1lQBKifxTB",
        "outputId": "73b67454-fb6b-4bb5-80af-61c22eef77f6"
      },
      "source": [
        "prediction_score = model.evaluate(X_test, Y_test, verbose=0)\n",
        "\n",
        "print('Test Loss and Test Accuracy', prediction_score)"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Test Loss and Test Accuracy [0.032096538692712784, 0.9911999702453613]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "IjEgppYiXnaY"
      },
      "source": [
        "from keras.preprocessing import image\n",
        "from keras.utils import array_to_img, img_to_array, load_img"
      ],
      "execution_count": 22,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 282
        },
        "id": "Rtdsx5HWXxAj",
        "outputId": "5a9a992c-ad48-4ad9-ad0e-a0f544ff4525"
      },
      "source": [
        "plt.imshow(array_to_img(X_test[46]), cmap=\"gray\")"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<matplotlib.image.AxesImage at 0x7f13b77517f0>"
            ]
          },
          "metadata": {},
          "execution_count": 16
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ],
            "image/png": "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\n"
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8pHoyL4mXxDc",
        "outputId": "70beeff1-d674-4bb9-d512-39f778248458"
      },
      "source": [
        "y_test[46]"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "1"
            ]
          },
          "metadata": {},
          "execution_count": 17
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "IoQ6-V_l2G6L"
      },
      "source": [
        "#####################################################################################"
      ],
      "execution_count": 18,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/content/drive')"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "U4-Je251-_68",
        "outputId": "81a9f9c5-9f07-468e-9f41-ea2717155244"
      },
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tPUmPTkbWw01"
      },
      "source": [
        "def identify_digit(digit):\n",
        "  dir_path = '/content/drive/MyDrive/Colab Notebooks/data/mnist_imgs/'\n",
        "  img = load_img(path=dir_path+f\"{digit}.PNG\", grayscale=True, target_size=(28, 28))\n",
        "  img = img_to_array(img)\n",
        "  # plt.imshow(array_to_img(img), cmap=\"gray\")\n",
        "  img = img.astype('float')/255\n",
        "  test_img = img.reshape((1, 28, 28, 1))\n",
        "\n",
        "  # Prediction code for tensorflow version >= 2.6 (latest 2.6.0)\n",
        "  image_class = model.predict(test_img) \n",
        "  prediction = np.argmax(image_class, axis=1)\n",
        "\n",
        "  # Prediction code for tensorflow version < 2.6\n",
        "  # img_class = model.predict_classes(test_img)\n",
        "  # prediction = img_class[0]\n",
        "\n",
        "  return prediction"
      ],
      "execution_count": 27,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3gILuNCfn8Cu",
        "outputId": "6f52fd77-4737-4f21-98e1-363b59c9944b"
      },
      "source": [
        "identify_digit(8)"
      ],
      "execution_count": 28,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 20ms/step\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([8])"
            ]
          },
          "metadata": {},
          "execution_count": 28
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "GbYwFZ2i_raT"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}